home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-02-19 | 55.3 KB | 2,722 lines |
- MODULE KERFIL (IDENT = '3.3.119',
- ADDRESSING_MODE(EXTERNAL = GENERAL, NONEXTERNAL = GENERAL)) =
- BEGIN
- !<BLF/WIDTH:90>
-
- !++
- ! FACILITY:
- ! KERMIT-32 Microcomputer to mainframe file transfer utility.
- !
- ! ABSTRACT:
- ! KERFIL contains all of the file processing for KERMIT-32. This
- ! module contains the routines to input/output characters to files
- ! and to open and close the files.
- !
- ! ENVIRONMENT:
- ! VAX/VMS user mode.
- !
- ! AUTHOR: Robert C. McQueen, CREATION DATE: 28-March-1983
- !
- !--
-
- %SBTTL 'Table of Contents'
- %SBTTL 'Revision History'
-
- !++
- !
- ! 1.0.000 By: Robert C. McQueen On: 28-March-1983
- ! Create this module.
- ! 1.0.001 By: Robert C. McQueen On: 4-April-1983
- ! Remove checks for <FF> in the input data stream.
- !
- ! 1.0.002 By: Robert C. McQueen On: 31-May-1983
- ! Fix a bad check in wildcard processing.
- !
- ! 1.0.003 By: Nick Bush On: 13-June-1983
- ! Add default file spec of .;0 so that wild-carded
- ! file types don't cause all version of a file to
- ! be transferred.
- !
- ! 1.0.004 By: Robert C. McQueen On: 20-July-1983
- ! Strip off the parity bit on the compares for incoming ASCII
- ! files.
- !
- ! 1.2.005 By: Robert C. McQueen On: 15-August-1983
- ! Attempt to improve the GET%FILE and make it smaller.
- ! Also start the implementation of the BLOCK file processing.
- !
- ! 2.0.006 Release VAX/VMS Kermit-32 version 2.0
- !
- ! 2.0.016 By: Nick Bush On: 4-Dec-1983
- ! Change how binary files are written to (hopefully) improve
- ! the performance. We will now use 510 records and only
- ! write out the record when it is filled (instead of writing
- ! one record per packet). This should cut down on the overhead
- ! substantially.
- !
- ! 2.0.017 By: Nick Bush On: 9-Dec-1983
- ! Fix processing for VFC format files. Also fix GET_ASCII
- ! for PRN and FTN record types. Change GET_ASCII so that
- ! 'normal' CR records get sent with trailing CRLF's instead
- ! of <LF>record<CR>. That was confusing too many people.
- !
- ! 2.0.022 By: Nick Bush On: 15-Dec-1983
- ! Add Fixed record size (512 byte) format for writing files.
- ! This can be used for .EXE files. Also clean up writing
- ! ASCII files so that we don't lose any characters.
- !
- ! 2.0.024 By: Robert C. McQueen On: 19-Dec-1983
- ! Delete FILE_DUMP.
- !
- ! 2.0.026 By: Nick Bush On: 3-Jan-1983
- ! Add options for format of file specification to be
- ! sent in file header packets. Also type out full file
- ! specification being sent/received instead of just
- ! the name we are telling the other end to use.
- !
- ! 2.0.030 By: Nick Bush On: 3-Feb-1983
- ! Add the capability of receiving a file with a different
- ! name than given by KERMSG. The RECEIVE and GET commands
- ! now really are different.
- !
- ! 2.0.035 By: Nick Bush On: 8-March-1984
- ! Add LOG SESSION command to set a log file for CONNECT.
- ! While we are doing so, clean up the command parsing a little
- ! so that we don't have as many COPY_xxx routines.
- !
- ! 2.0.036 By: Nick Bush On: 15-March-1984
- ! Fix PUT_FILE to correctly handle carriage returns which are
- ! not followed by line feeds. Count was being decremented
- ! Instead of incremented.
- !
- ! 2.0.040 By: Nick Bush On: 22-March-1984
- ! Fix processing of FORTRAN carriage control to handle lines
- ! which do not contain the carriage control character (i.e., zero
- ! length records). Previously, this type of record was sending
- ! infinite nulls.
- !
- ! 3.0.045 Start of version 3.
- !
- ! 3.0.046 By: Nick Bush On: 29-March-1984
- ! Fix debugging log file to correctly set/clear file open
- ! flag. Also make log files default to .LOG.
- !
- ! 3.0.050 By: Nick Bush On: 2-April-1984
- ! Add SET SERVER_TIMER to determine period between idle naks.
- ! Also allow for a routine to process file specs before
- ! FILE_OPEN uses them. This allows individual sites to
- ! restrict the format of file specifications used by Kermit.
- !
- ! 3.1.053 By: Robert C. McQueen On: 9-July-1984
- ! Fix FORTRAN carriage control processing to pass along
- ! any character from the carriage control column that is
- ! not really carriage control.
- !
- ! Start version 3.2
- !
- ! 3.2.067 By: Robert C. McQueen On: 8-May-1985
- ! Use $GETDVIW instead of $GETDVI.
- !
- ! 3.2.070 By: David Stevens On: 16-July-1985
- ! Put "Sending: " prompt into NEXT_FILE routine, to make
- ! VMS KERMIT similar to KERMIT-10.
- !
- ! 3.2.077 By: Robert McQueen On: 8-May-1986
- ! Fix FORTRAN CC once and for all (I hope).
- !
- ! Start of version 3.3
- !
- ! 3.3.105 By: Robert McQueen On: 8-July-1986
- ! Do some clean up and attempt to fix LINK-W-TRUNC errors
- ! from a BLISS-32 bug.
- !
- ! 3.3.106 By: Robert McQueen On: 8-July-1986
- ! Fix problem of closing a fixed file and losing data.
- !
- ! 3.3.111 By: Robert McQueen On: 2-Oct-1986
- ! Make Kermit-32 not eat the parity from a CR if a LF doesn't
- ! follow it when writing an ASCII file.
- !
- ! 3.3.112 JHW0001 Jonathan H. Welch, 28-Apr-1988 12:11
- ! Fix the message generated in NEXT_FILE so that the
- ! filenames displayed (i.e. Sending: foo.bar;1 as foo.bar)
- ! are always terminated by a null (ASCIZ).
- !
- ! 3.3.117 JHW006 Jonathan H. Welch, 12-May-1988
- ! Calls to LIB$SIGNAL with multiple arguments were
- ! not coded correctly. For calls with multiple arguments
- ! an argument count was added.
- ! Minor changes to KERM_HANDLER to make use of the changed
- ! argument passing method.
- !
- ! 3.3.118 JHW010 Jonathan H. Welch, 23-Apr-1990 09:42
- ! Added SET FILE BLOCKSIZE nnn (where nnn is the record size
- ! in bytes) command for incoming BINARY and FIXED file transfers.
- ! If no blocksize has been specified the old behavior (510 byte
- ! records plus 2 bytes (for CR/LF) for BINARY files and 512
- ! byte records for FIXED files will be used.
- ! Also modified SHOW FILE to display record size when appropriate.
- !
- ! 3.3.119 JHW015 Jonathan H. Welch, 16-Jul-1990 15:30
- ! Fixed the logic in GET_ASCII which was causing an infinite
- ! loop for files with print file carriage control.
- !--
-
- %SBTTL 'Forward definitions'
-
- FORWARD ROUTINE
- LOG_PUT, ! Write a buffer out
- DUMP_BUFFER, ! Worker routine for FILE_DUMP.
- GET_BUFFER, ! Routine to do $GET
- GET_ASCII, ! Get an ASCII character
- GET_BLOCK, ! Get a block character
- FILE_ERROR : NOVALUE; ! Error processing routine
-
- %SBTTL 'Require/Library files'
- !
- ! INCLUDE FILES:
- !
-
- LIBRARY 'SYS$LIBRARY:STARLET';
-
- REQUIRE 'KERCOM.REQ';
-
- %SBTTL 'Macro definitions'
- !
- ! MACROS:
- !
- %SBTTL 'Literal symbol definitions'
- !
- ! EQUATED SYMBOLS:
- !
- !
- ! Various states for reading the data from the file
- !
-
- LITERAL
- F_STATE_PRE = 0, ! Prefix state
- F_STATE_PRE1 = 1, ! Other prefix state
- F_STATE_DATA = 2, ! Data processing state
- F_STATE_POST = 3, ! Postfix processing state
- F_STATE_POST1 = 4, ! Secondary postfix processing state
- F_STATE_MIN = 0, ! Min state number
- F_STATE_MAX = 4; ! Max state number
-
- !
- ! Buffer size for log file
- !
-
- LITERAL
- LOG_BUFF_SIZE = 256; ! Number of bytes in log file buffer
-
- %SBTTL 'Local storage'
- !
- ! OWN STORAGE:
- !
-
- OWN
- SEARCH_FLAG, ! Can/cannot do $SEARCH
- DEV_CLASS, ! Type of device we are reading
- EOF_FLAG, ! End of file reached.
- FILE_FAB : $FAB_DECL, ! FAB for file processing
- FILE_NAM : $NAM_DECL, ! NAM for file processing
- FILE_RAB : $RAB_DECL, ! RAB for file processing
- FILE_XABFHC : $XABFHC_DECL, ! XAB for file processing
- FILE_MODE, ! Mode of file (reading/writing)
- FILE_REC_POINTER, ! Pointer to the record information
- FILE_REC_COUNT, ! Count of the number of bytes
- REC_SIZE : LONG, ! Record size
- REC_ADDRESS : LONG, ! Record address
- FIX_SIZE : LONG, ! Fixed control region size
- FIX_ADDRESS : LONG, ! Address of buffer for fixed control region
- EXP_STR : VECTOR [CH$ALLOCATION (NAM$C_MAXRSS)],
- RES_STR : VECTOR [CH$ALLOCATION (NAM$C_MAXRSS)],
- RES_STR_D : BLOCK [8, BYTE]; ! Descriptor for the string
-
- %SBTTL 'Global storage'
- !
- ! Global storage:
- !
-
- GLOBAL
-
- file_blocksize, ! Block size of for BINARY and FIXED files.
- file_blocksize_set, ! 0=user has not specified a blocksize, 1=user has specified a blocksize
- FILE_TYPE, ! Type of file being xfered
- FILE_DESC : BLOCK [8, BYTE]; ! File name descriptor
-
- %SBTTL 'External routines and storage'
- !
- ! EXTERNAL REFERENCES:
- !
- !
- ! Storage in KERMSG
- !
-
- EXTERNAL
- ALT_FILE_SIZE, ! Number of characters in FILE_NAME
- ALT_FILE_NAME : VECTOR [CH$ALLOCATION (MAX_FILE_NAME)], ! Storage
- FILE_SIZE, ! Number of characters in FILE_NAME
- FILE_NAME : VECTOR [CH$ALLOCATION (MAX_FILE_NAME)],
- TY_FIL, ! Flag that file names are being typed
- CONNECT_FLAG, ! Indicator of whether we have a terminal to type on
- FIL_NORMAL_FORM; ! File specification type
-
- !
- ! Routines in KERTT
- !
-
- EXTERNAL ROUTINE
- TT_OUTPUT : NOVALUE; ! Force buffered output
-
- !
- ! System libraries
- !
-
- EXTERNAL ROUTINE
- LIB$GET_VM : ADDRESSING_MODE (GENERAL),
- LIB$FREE_VM : ADDRESSING_MODE (GENERAL),
- LIB$SIGNAL : ADDRESSING_MODE (GENERAL) NOVALUE;
-
- %SBTTL 'File processing -- FILE_INIT - Initialization'
-
- GLOBAL ROUTINE FILE_INIT : NOVALUE =
-
- !++
- ! FUNCTIONAL DESCRIPTION:
- !
- ! This routine will initialize some of the storage in the file processing
- ! module.
- !
- ! CALLING SEQUENCE:
- !
- ! FILE_INIT();
- !
- ! INPUT PARAMETERS:
- !
- ! None.
- !
- ! IMPLICIT INPUTS:
- !
- ! None.
- !
- ! OUTPUT PARAMETERS:
- !
- ! None.
- !
- ! IMPLICIT OUTPUTS:
- !
- ! None.
- !
- ! COMPLETION CODES:
- !
- ! None.
- !
- ! SIDE EFFECTS:
- !
- ! None.
- !
- !--
-
- BEGIN
- FILE_TYPE = FILE_ASC;
- file_blocksize = 512;
- file_blocksize_set = 0;
-
- ! Now set up the file specification descriptor
- FILE_DESC [DSC$B_CLASS] = DSC$K_CLASS_S;
- FILE_DESC [DSC$B_DTYPE] = DSC$K_DTYPE_T;
- FILE_DESC [DSC$A_POINTER] = FILE_NAME;
- FILE_DESC [DSC$W_LENGTH] = 0;
- EOF_FLAG = FALSE;
- END; ! End of FILE_INIT
-
- %SBTTL 'GET_FILE'
-
- GLOBAL ROUTINE GET_FILE (CHARACTER) =
-
- !++
- ! FUNCTIONAL DESCRIPTION:
- !
- ! This routine will return a character from the input file.
- ! The character will be stored into the location specified by
- ! CHARACTER.
- !
- ! CALLING SEQUENCE:
- !
- ! GET_FILE (LOCATION_TO_STORE_CHAR);
- !
- ! INPUT PARAMETERS:
- !
- ! LOCATION_TO_STORE_CHAR - This is the address to store the character
- ! into.
- !
- ! IMPLICIT INPUTS:
- !
- ! None.
- !
- ! OUTPUT PARAMETERS:
- !
- ! Character stored into the location specified.
- !
- ! IMPLICIT OUTPUTS:
- !
- ! None.
- !
- ! COMPLETION CODES:
- !
- ! True - Character stored into the location specified.
- ! False - End of file reached.
- !
- ! SIDE EFFECTS:
- !
- ! None.
- !
- !--
-
- BEGIN
- !
- ! Define the various condition codes that we check for in this routine
- !
- EXTERNAL LITERAL
- KER_EOF; ! End of file
-
- LOCAL
- STATUS; ! Random status values
-
- IF .EOF_FLAG THEN RETURN KER_EOF;
-
- SELECTONE .FILE_TYPE OF
- SET
-
- [FILE_ASC, FILE_BIN, FILE_FIX] :
- STATUS = GET_ASCII (.CHARACTER);
-
- [FILE_BLK] :
- STATUS = GET_BLOCK (.CHARACTER);
- TES;
-
- RETURN .STATUS;
- END; ! End of GET_FILE
- %SBTTL 'GET_ASCII - Get a character from an ASCII file'
- ROUTINE GET_ASCII (CHARACTER) =
-
- !++
- ! FUNCTIONAL DESCRIPTION:
- !
- ! CALLING SEQUENCE:
- !
- ! INPUT PARAMETERS:
- !
- ! None.
- !
- ! IMPLICIT INPUTS:
- !
- ! None.
- !
- ! OUPTUT PARAMETERS:
- !
- ! None.
- !
- ! IMPLICIT OUTPUTS:
- !
- ! None.
- !
- ! COMPLETION CODES:
- !
- ! KER_EOF - End of file encountered
- ! KER_ILLFILTYP - Illegal file type
- ! KER_NORMAL - Normal return
- !
- ! SIDE EFFECTS:
- !
- ! None.
- !
- !--
-
- BEGIN
- !
- ! Status codes that are returned by this module
- !
- EXTERNAL LITERAL
- KER_EOF, ! End of file encountered
- KER_ILLFILTYP, ! Illegal file type
- KER_NORMAL; ! Normal return
-
- OWN
- CC_COUNT, ! Count of the number of CC things to output
- CC_TYPE; ! Type of carriage control being processed.
-
- LOCAL
- STATUS, ! For status values
- RAT;
- %SBTTL 'GET_FTN_FILE_CHARACTER - Get a character from an Fortran carriage control file'
- ROUTINE GET_FTN_FILE_CHARACTER (CHARACTER) =
- !++
- ! FUNCTIONAL DESCRIPTION:
- !
- ! This routine will get a character from a FORTRAN carriage control file.
- ! A FORTRAN carriage control file is one with FAB$M_FTN on in the FAB$B_RAT
- ! field.
- !
- ! FORMAL PARAMETERS:
- !
- ! CHARACTER - Address of where to store the character
- !
- ! IMPLICIT INPUTS:
- !
- ! CC_TYPE - Carriage control type
- !
- ! IMPLICIT OUTPUTS:
- !
- ! CC_TYPE - Updated if this is the first characte of the record
- !
- ! COMPLETION_CODES:
- !
- ! System service or Kermit status code
- !
- ! SIDE EFFECTS:
- !
- ! Next buffer can be read from the data file.
- !--
- BEGIN
- !
- ! Dispatch according to the state of the file being read. Beginning of
- ! record, middle of record, end of record
- !
- WHILE TRUE DO
- CASE .FILE_FAB[FAB$L_CTX] FROM F_STATE_MIN TO F_STATE_MAX OF
- SET
- !
- ! Here at the beginning of a record. We must read the buffer from the file
- ! at this point. Once the buffer is read we must then determine what to do
- ! with the FORTRAN carriage control that at the beginning of the buffer.
- !
- [F_STATE_PRE ]:
- BEGIN
- !
- ! Local variables
- !
- LOCAL
- STATUS; ! Status returned by the
- ! GET_BUFFER routine
- !
- ! Get the buffer
- !
- STATUS = GET_BUFFER (); ! Get a buffer from the system
- IF (NOT .STATUS) ! If this call failed
- OR (.STATUS EQL KER_EOF) ! or we got an EOF
- THEN
- RETURN .STATUS; ! Just return the status
- !
- ! Here with a valid buffer full of data all set to be decoded
- !
- IF .FILE_REC_COUNT LEQ 0 ! If nothing, use a space
- THEN ! for the carriage control
- CC_TYPE = %C' '
- ELSE
- BEGIN
- CC_TYPE = CH$RCHAR_A (FILE_REC_POINTER);
- FILE_REC_COUNT = .FILE_REC_COUNT - 1;
- END;
- !
- ! Dispatch on the type of carriage control that we are processing
- !
- SELECTONE .CC_TYPE OF
- SET
- !
- ! All of these just output:
- ! <DATA> <Carriage-control>
- !
- [CHR_NUL, %C'+'] :
- BEGIN
- FILE_FAB [FAB$L_CTX] = F_STATE_DATA;
- END;
- !
- ! This outputs:
- ! <LF><DATA><CR>
- !
- [%C'$', %C' '] :
- BEGIN
- .CHARACTER = CHR_LFD;
- FILE_FAB [FAB$L_CTX] = F_STATE_DATA;
- RETURN KER_NORMAL;
- END;
- !
- ! This outputs:
- ! <LF><LF><DATA><CR>
- !
- [%C'0'] :
- BEGIN
- .CHARACTER = CHR_LFD;
- FILE_FAB [FAB$L_CTX] = F_STATE_PRE1;
- RETURN KER_NORMAL;
- END;
- !
- ! This outputs:
- ! <FORM FEED><DATA><CR>
- !
- [%C'1'] :
- BEGIN
- .CHARACTER = CHR_FFD;
- FILE_FAB [FAB$L_CTX] = F_STATE_DATA;
- RETURN KER_NORMAL;
- END;
- !
- ! If we don't know the type of carriage control, then just return the
- ! character we read as data and set the carriage control to be space
- ! to fool the post processing of the record
- !
- [OTHERWISE] :
- BEGIN
- .CHARACTER = .CC_TYPE; ! Return the character
- CC_TYPE = %C' '; ! Treat as space
- FILE_REC_POINTER = CH$PLUS(.FILE_REC_POINTER,-1);
- FILE_REC_COUNT = .FILE_REC_COUNT + 1;
- FILE_FAB [FAB$L_CTX] = F_STATE_DATA;
- RETURN KER_NORMAL
- END;
- TES;
-
- END;
- !
- ! Here to add the second LF for the double spacing FORTRAN carriage control
- !
- [F_STATE_PRE1 ]:
- BEGIN
- .CHARACTER = CHR_LFD;
- FILE_FAB [FAB$L_CTX] = F_STATE_DATA;
- RETURN KER_NORMAL;
- END;
- !
- ! Here to read the data of the record
- !
- [F_STATE_DATA]:
- BEGIN
- !
- ! Here to read the data of the record and return it to the caller
- ! This section can only return KER_NORMAL to the caller
- !
- IF .FILE_REC_COUNT LEQ 0 ! Anything left in the buffer
- THEN
- FILE_FAB [FAB$L_CTX] = F_STATE_POST ! No, do post processing
- ELSE
- BEGIN
- .CHARACTER = CH$RCHAR_A (FILE_REC_POINTER); ! Get a character
- FILE_REC_COUNT = .FILE_REC_COUNT - 1; ! Decrement the count
- RETURN KER_NORMAL; ! Give a good return
- END;
- END;
- !
- ! Here to do post processing of the record. At this point we are going
- ! to store either nothing as the post fix, a carriage return for overprinting
- ! or a carriage return and then a line feed in the POST1 state.
- !
- [F_STATE_POST ]:
- BEGIN
- SELECTONE .CC_TYPE OF
- SET
- !
- ! This stat is for no carriage control on the record. This is for
- ! 'null' carriage control (VMS manual states: "Null carriage control
- ! (print buffer contents.)" and for prompt carriage control.
- !
- [CHR_NUL, %C'$' ]:
- BEGIN
- FILE_FAB [FAB$L_CTX] = F_STATE_PRE
- END;
- !
- ! This is the normal state, that causes the postfix for the data to be
- ! a line feed.
- !
- [%C'0', %C'1', %C' ', %C'+' ]:
- BEGIN
- .CHARACTER = CHR_CRT;
- FILE_FAB [FAB$L_CTX] = F_STATE_PRE;
- RETURN KER_NORMAL
- END;
- TES;
-
- END;
- !
- ! Here if we are in a state that this routine doesn't set. Just assume that
- ! something screwed up and give an illegal file type return to the caller
- !
- [INRANGE, OUTRANGE]:
- RETURN KER_ILLFILTYP;
-
- TES
- END;
- %SBTTL 'GET_ASCII - Main logic'
- RAT = .FILE_FAB [FAB$B_RAT] AND ( NOT FAB$M_BLK);
-
- IF .DEV_CLASS EQL DC$_MAILBOX THEN RAT = FAB$M_CR; ! Mailbox needs CR's
-
- WHILE TRUE DO
- BEGIN
-
- SELECTONE .RAT OF
- SET
-
- [FAB$M_FTN ]:
- BEGIN
- RETURN GET_FTN_FILE_CHARACTER (.CHARACTER)
- END;
-
- [FAB$M_PRN, FAB$M_CR] :
-
- CASE .FILE_FAB [FAB$L_CTX] FROM F_STATE_MIN TO F_STATE_MAX OF
- SET
-
- [F_STATE_PRE] :
- BEGIN
- STATUS = GET_BUFFER ();
-
- IF NOT .STATUS OR .STATUS EQL KER_EOF THEN RETURN .STATUS;
-
- SELECTONE .RAT OF
- SET
-
- [FAB$M_CR] :
- BEGIN
- FILE_FAB [FAB$L_CTX] = F_STATE_DATA;
- END;
-
- [FAB$M_PRN] :
- BEGIN
-
- LOCAL
- TEMP_POINTER;
-
- TEMP_POINTER = CH$PTR (.FILE_RAB [RAB$L_RHB]);
- CC_COUNT = CH$RCHAR_A (TEMP_POINTER);
- CC_TYPE = CH$RCHAR_A (TEMP_POINTER);
-
- IF .CC_COUNT<7, 1> EQL 0
- THEN
- BEGIN
-
- IF .CC_COUNT<0, 7> NEQ 0
- THEN
- BEGIN
- .CHARACTER = CHR_LFD;
- CC_COUNT = .CC_COUNT - 1;
-
- IF .CC_COUNT GTR 0
- THEN
- FILE_FAB [FAB$L_CTX] = F_STATE_PRE1
- ELSE
- FILE_FAB [FAB$L_CTX] = F_STATE_DATA;
-
- RETURN KER_NORMAL;
- END
- ELSE
- FILE_FAB [FAB$L_CTX] = F_STATE_DATA;
-
- END
- ELSE
- BEGIN
-
- SELECTONE .CC_COUNT<5, 2> OF
- SET
-
- [%B'00'] :
- BEGIN
- .CHARACTER = .CC_COUNT<0, 5>;
- FILE_FAB [FAB$L_CTX] = F_STATE_DATA;
- RETURN KER_NORMAL;
- END;
-
- [%B'10'] :
- BEGIN
- .CHARACTER = .CC_COUNT<0, 5> + 128;
- FILE_FAB [FAB$L_CTX] = F_STATE_DATA;
- RETURN KER_NORMAL;
- END;
-
- [OTHERWISE, %B'11'] :
- RETURN KER_ILLFILTYP;
- TES;
- END;
- END;
- TES;
-
- END;
-
- [F_STATE_PRE1] :
-
- IF .RAT EQL FAB$M_PRN
- THEN
- BEGIN
- .CHARACTER = CHR_LFD;
- CC_COUNT = .CC_COUNT - 1;
-
- IF .CC_COUNT LEQ 0 THEN FILE_FAB [FAB$L_CTX] = F_STATE_DATA;
-
- RETURN KER_NORMAL;
- END
- ELSE
- RETURN KER_ILLFILTYP;
-
- [F_STATE_DATA] :
- BEGIN
-
- IF .FILE_REC_COUNT LEQ 0
- THEN
- FILE_FAB [FAB$L_CTX] = F_STATE_POST
- ELSE
- BEGIN
- .CHARACTER = CH$RCHAR_A (FILE_REC_POINTER);
- FILE_REC_COUNT = .FILE_REC_COUNT - 1;
- RETURN KER_NORMAL;
- END;
-
- END;
-
- [F_STATE_POST] :
- BEGIN
-
- SELECTONE .RAT OF
- SET
-
- [FAB$M_CR] :
- BEGIN
- .CHARACTER = CHR_CRT;
- FILE_FAB [FAB$L_CTX] = F_STATE_POST1;
- ! So we get a line feed
- RETURN KER_NORMAL;
- END;
-
-
- [FAB$M_PRN] :
- BEGIN
-
- IF .CC_TYPE<7, 1> EQL 0
- THEN
- BEGIN
-
- IF .CC_TYPE<0, 7> NEQ 0
- THEN
- BEGIN
- .CHARACTER = CHR_LFD;
- CC_COUNT = .CC_TYPE;
- FILE_FAB [FAB$L_CTX] = F_STATE_POST1;
- RETURN KER_NORMAL;
- END
- ELSE
- FILE_FAB [FAB$L_CTX] = F_STATE_PRE;
- END
- ELSE
- BEGIN
-
- SELECTONE .CC_TYPE<5, 2> OF
- SET
-
- [%B'00'] :
- BEGIN
- .CHARACTER = .CC_TYPE<0, 5>;
- FILE_FAB [FAB$L_CTX] = F_STATE_PRE;
- RETURN KER_NORMAL;
- END;
-
- [%B'10'] :
- BEGIN
- .CHARACTER = .CC_TYPE<0, 5> + 128;
- FILE_FAB [FAB$L_CTX] = F_STATE_PRE;
- RETURN KER_NORMAL;
- END;
-
- [OTHERWISE, %B'11'] :
- RETURN KER_ILLFILTYP;
- TES;
-
- END;
-
- END;
- TES; ! End SELECTONE .RAT
-
- END;
-
- [F_STATE_POST1] :
-
- IF .RAT EQL FAB$M_PRN
- THEN
- BEGIN
- .CHARACTER = CHR_LFD;
- CC_COUNT = .CC_COUNT - 1;
-
- IF .CC_COUNT LEQ -1
- THEN
- BEGIN
- .CHARACTER = CHR_CRT;
- ! FILE_FAB [FAB$L_CTX] = F_STATE_DATA;
- FILE_FAB [FAB$L_CTX] = F_STATE_PRE;
- END;
-
- RETURN KER_NORMAL;
- END
- ELSE
- !
- ! Generate line feed after CR for funny files
- !
-
- IF (.RAT EQL FAB$M_CR)
- THEN
- BEGIN
- .CHARACTER = CHR_LFD; ! Return a line feed
- FILE_FAB [FAB$L_CTX] = F_STATE_PRE;
- ! Next we get data
- RETURN KER_NORMAL;
- END
- ELSE
- RETURN KER_ILLFILTYP;
-
- TES; ! End of CASE .STATE
-
- [OTHERWISE] :
- BEGIN
-
- WHILE .FILE_REC_COUNT LEQ 0 DO
- BEGIN
- STATUS = GET_BUFFER ();
-
- IF NOT .STATUS OR .STATUS EQL KER_EOF THEN RETURN .STATUS;
-
- END;
-
- FILE_REC_COUNT = .FILE_REC_COUNT - 1;
- .CHARACTER = CH$RCHAR_A (FILE_REC_POINTER);
- RETURN KER_NORMAL;
- END;
- TES; ! End of SELECTONE .RAT
-
- END; ! End WHILE TRUE DO loop
-
- RETURN KER_ILLFILTYP; ! Shouldn't get here
- END; ! End of GET_ASCII
- %SBTTL 'GET_BLOCK - Get a character from a BLOCKed file'
- ROUTINE GET_BLOCK (CHARACTER) =
-
- !++
- ! FUNCTIONAL DESCRIPTION:
- !
- ! This routine will return the next byte from a blocked file. This
- ! routine will use the $READ RMS call to get the next byte from the
- ! file. This way all RMS header information can be passed to the
- ! other file system.
- !
- ! CALLING SEQUENCE:
- !
- ! STATUS = GET_BLOCK(CHARACTER);
- !
- ! INPUT PARAMETERS:
- !
- ! CHARACTER - Address to store the character in.
- !
- ! IMPLICIT INPUTS:
- !
- ! REC_POINTER - Pointer into the record.
- ! REC_ADDRESS - Address of the record.
- ! REC_COUNT - Count of the number of bytes left in the record.
- !
- ! OUPTUT PARAMETERS:
- !
- ! None.
- !
- ! IMPLICIT OUTPUTS:
- !
- ! None.
- !
- ! COMPLETION CODES:
- !
- ! KER_NORMAL - Got a byte
- ! KER_EOF - End of file gotten.
- ! KER_RMS32 - RMS error
- !
- ! SIDE EFFECTS:
- !
- ! None.
- !
- !--
-
- BEGIN
- !
- ! Status codes returned by this module
- !
- EXTERNAL LITERAL
- KER_RMS32, ! RMS error encountered
- KER_EOF, ! End of file encountered
- KER_NORMAL; ! Normal return
-
- LOCAL
- STATUS; ! Random status values
-
- WHILE .FILE_REC_COUNT LEQ 0 DO
- BEGIN
- STATUS = $READ (RAB = FILE_RAB);
-
- IF NOT .STATUS
- THEN
-
- IF .STATUS EQL RMS$_EOF
- THEN
- BEGIN
- EOF_FLAG = TRUE;
- RETURN KER_EOF;
- END
- ELSE
- BEGIN
- FILE_ERROR (.STATUS);
- EOF_FLAG = TRUE;
- RETURN KER_RMS32;
- END;
-
- FILE_REC_POINTER = CH$PTR (.REC_ADDRESS);
- FILE_REC_COUNT = .FILE_RAB [RAB$W_RSZ];
- END;
-
- FILE_REC_COUNT = .FILE_REC_COUNT - 1;
- .CHARACTER = CH$RCHAR_A (FILE_REC_POINTER);
- RETURN KER_NORMAL;
- END; ! End of GET_BLOCK
- %SBTTL 'GET_BUFFER - Routine to read a buffer.'
- ROUTINE GET_BUFFER =
-
- !++
- ! FUNCTIONAL DESCRIPTION:
- !
- ! This routine will read a buffer from the disk file. It will
- ! return various status depending if there was an error reading
- ! the disk file or if the end of file is reached.
- !
- ! CALLING SEQUENCE:
- !
- ! STATUS = GET_BUFFER ();
- !
- ! INPUT PARAMETERS:
- !
- ! None.
- !
- ! IMPLICIT INPUTS:
- !
- ! None.
- !
- ! OUTPUT PARAMETERS:
- !
- ! None.
- !
- ! IMPLICIT OUTPUTS:
- !
- ! FILE_REC_POINTER - Pointer into the record.
- ! FILE_REC_COUNT - Count of the number of bytes in the record.
- !
- ! COMPLETION CODES:
- !
- ! KER_NORMAL - Got a buffer
- ! KER_EOF - End of file reached.
- ! KER_RMS32 - RMS error
- !
- ! SIDE EFFECTS:
- !
- ! None.
- !
- !--
-
- BEGIN
- !
- ! The following are the various status values returned by this routien
- !
- EXTERNAL LITERAL
- KER_NORMAL, ! Normal return
- KER_EOF, ! End of file
- KER_RMS32; ! RMS error encountered
-
- LOCAL
- STATUS; ! Random status values
-
- STATUS = $GET (RAB = FILE_RAB);
-
- IF NOT .STATUS
- THEN
-
- IF .STATUS EQL RMS$_EOF
- THEN
- BEGIN
- EOF_FLAG = TRUE;
- RETURN KER_EOF;
- END
- ELSE
- BEGIN
- FILE_ERROR (.STATUS);
- EOF_FLAG = TRUE;
- RETURN KER_RMS32;
- END;
-
- FILE_REC_POINTER = CH$PTR (.REC_ADDRESS);
- FILE_REC_COUNT = .FILE_RAB [RAB$W_RSZ];
- RETURN KER_NORMAL;
- END;
- %SBTTL 'PUT_FILE'
-
- GLOBAL ROUTINE PUT_FILE (CHARACTER) =
-
- !++
- ! FUNCTIONAL DESCRIPTION:
- !
- ! This routine will store a character into the record buffer
- ! that we are building. It will output the buffer to disk
- ! when the end of line characters are found.
- !
- ! CALLING SEQUENCE:
- !
- ! STATUS = PUT_FILE(Character);
- !
- ! INPUT PARAMETERS:
- !
- ! Character - Address of the character to output in the file.
- !
- ! IMPLICIT INPUTS:
- !
- ! None.
- !
- ! OUTPUT PARAMETERS:
- !
- ! Status - True if no problems writing the character
- ! False if there were problems writing the character.
- !
- ! IMPLICIT OUTPUTS:
- !
- ! None.
- !
- ! COMPLETION CODES:
- !
- ! None.
- !
- ! SIDE EFFECTS:
- !
- ! None.
- !
- !--
-
- BEGIN
- !
- ! Completion codes
- !
- EXTERNAL LITERAL
- KER_REC_TOO_BIG, ! Record too big
- KER_NORMAL; ! Normal return
- !
- ! Local variables
- !
- OWN
- SAVED_CHARACTER : UNSIGNED BYTE; ! Character we may have to
- ! write later on
- LOCAL
- STATUS; ! Random status values
-
- SELECTONE .FILE_TYPE OF
- SET
-
- [FILE_ASC] :
- BEGIN
- !
- ! If the last character was a carriage return and this is a line feed,
- ! we will just dump the record. Otherwise, if the last character was
- ! a carriage return, output both it and the current one.
- !
-
- IF .FILE_FAB [FAB$L_CTX] NEQ F_STATE_DATA
- THEN
- BEGIN
-
- IF (.CHARACTER AND %O'177') EQL CHR_LFD
- THEN
- BEGIN
- FILE_FAB [FAB$L_CTX] = F_STATE_DATA;
- RETURN DUMP_BUFFER ();
- END
- ELSE
- BEGIN
-
- IF .FILE_REC_COUNT GEQ .REC_SIZE
- THEN
- BEGIN
- LIB$SIGNAL (KER_REC_TOO_BIG);
- RETURN KER_REC_TOO_BIG;
- END;
-
- CH$WCHAR_A (.SAVED_CHARACTER, FILE_REC_POINTER);
- ! Store the carriage return we deferred
- FILE_REC_COUNT = .FILE_REC_COUNT + 1;
- FILE_FAB [FAB$L_CTX] = F_STATE_DATA; ! Back to normal data
- END;
-
- END;
-
- !
- ! Here when last character was written to the file normally. Check if
- ! this character might be the end of a record (or at least the start of
- ! end.
- !
-
- IF (.CHARACTER AND %O'177') EQL CHR_CRT
- THEN
- BEGIN
- SAVED_CHARACTER = .CHARACTER; ! Save the character for later
- FILE_FAB [FAB$L_CTX] = F_STATE_POST; ! Remember we saw this
- RETURN KER_NORMAL; ! And delay until next character
- END;
-
- IF .FILE_REC_COUNT GEQ .REC_SIZE
- THEN
- BEGIN
- LIB$SIGNAL (KER_REC_TOO_BIG);
- RETURN KER_REC_TOO_BIG;
- END;
-
- FILE_REC_COUNT = .FILE_REC_COUNT + 1;
- CH$WCHAR_A (.CHARACTER, FILE_REC_POINTER);
- END;
-
- [FILE_BIN, FILE_FIX] :
- BEGIN
-
- IF .FILE_REC_COUNT GEQ .REC_SIZE
- THEN
- BEGIN
- STATUS = DUMP_BUFFER ();
-
- IF NOT .STATUS
- THEN
- BEGIN
- LIB$SIGNAL (.STATUS);
- RETURN .STATUS;
- END;
-
- END;
-
- FILE_REC_COUNT = .FILE_REC_COUNT + 1;
- CH$WCHAR_A (.CHARACTER, FILE_REC_POINTER);
- END;
-
- [FILE_BLK] :
- BEGIN
-
- IF .FILE_REC_COUNT GEQ .REC_SIZE
- THEN
- BEGIN
- FILE_RAB [RAB$W_RSZ] = .FILE_REC_COUNT;
- STATUS = $WRITE (RAB = FILE_RAB);
- FILE_REC_COUNT = 0;
- FILE_REC_POINTER = CH$PTR (.REC_ADDRESS);
- END;
-
- FILE_REC_COUNT = .FILE_REC_COUNT + 1;
- CH$WCHAR_A (.CHARACTER, FILE_REC_POINTER);
- END;
- TES;
-
- RETURN KER_NORMAL;
- END; ! End of PUT_FILE
-
- %SBTTL 'DUMP_BUFFER - Dump the current record to disk'
- ROUTINE DUMP_BUFFER =
-
- !++
- ! FUNCTIONAL DESCRIPTION:
- !
- ! This routine will dump the current record to disk. It doesn't
- ! care what type of file you are writing, unlike FILE_DUMP.
- !
- ! CALLING SEQUENCE:
- !
- ! STATUS = DUMP_BUFFER();
- !
- ! INPUT PARAMETERS:
- !
- ! None.
- !
- ! IMPLICIT INPUTS:
- !
- ! None.
- !
- ! OUTPUT PARAMETERS:
- !
- ! None.
- !
- ! IMPLICIT OUTPUTS:
- !
- ! None.
- !
- ! COMPLETION CODES:
- !
- ! KER_NORMAL - Output went ok.
- ! KER_RMS32 - RMS-32 error.
- !
- ! SIDE EFFECTS:
- !
- ! None.
- !
- !--
-
- BEGIN
- !
- ! Completion codes returned:
- !
- EXTERNAL LITERAL
- KER_NORMAL, ! Normal return
- KER_RMS32; ! RMS-32 error
- !
- ! Local variables
- !
- LOCAL
- STATUS; ! Random status values
-
- !
- ! First update the record length
- !
- FILE_RAB [RAB$W_RSZ] = .FILE_REC_COUNT;
- !
- ! Now output the record to the file
- !
- STATUS = $PUT (RAB = FILE_RAB);
- !
- ! Update the pointers first
- !
- FILE_REC_COUNT = 0;
- FILE_REC_POINTER = CH$PTR (.REC_ADDRESS);
- !
- ! Now determine if we failed attempting to write the record
- !
-
- IF NOT .STATUS
- THEN
- BEGIN
- FILE_ERROR (.STATUS);
- RETURN KER_RMS32
- END;
-
- RETURN KER_NORMAL
- END; ! End of DUMP_BUFFER
- %SBTTL 'OPEN_READING'
- ROUTINE OPEN_READING =
-
- !++
- ! FUNCTIONAL DESCRIPTION:
- !
- ! This routine will open a file for reading. It will return either
- ! true or false to the called depending on the success of the
- ! operation.
- !
- ! CALLING SEQUENCE:
- !
- ! status = OPEN_READING();
- !
- ! INPUT PARAMETERS:
- !
- ! None.
- !
- ! IMPLICIT INPUTS:
- !
- ! None.
- !
- ! OUTPUT PARAMETERS:
- !
- ! None.
- !
- ! IMPLICIT OUTPUTS:
- !
- ! None.
- !
- ! COMPLETION CODES:
- !
- ! KER_NORMAL - Normal return
- ! KER_RMS32 - RMS error encountered
- !
- ! SIDE EFFECTS:
- !
- ! None.
- !
- !--
-
- BEGIN
- !
- ! Completion codes returned:
- !
- EXTERNAL LITERAL
- KER_NORMAL, ! Normal return
- KER_RMS32; ! RMS-32 error
-
- LOCAL
- STATUS; ! Random status values
-
- !
- ! We now have an expanded file specification that we can use to process
- ! the file.
- !
-
- IF .FILE_TYPE NEQ FILE_BLK
- THEN
- BEGIN
- $FAB_INIT (FAB = FILE_FAB, FAC = GET, FOP = NAM, RFM = STM, NAM = FILE_NAM,
- XAB = FILE_XABFHC);
- END
- ELSE
- BEGIN
- $FAB_INIT (FAB = FILE_FAB, FAC = (GET, BIO), FOP = NAM, RFM = STM,
- NAM = FILE_NAM, XAB = FILE_XABFHC);
- END;
-
- $XABFHC_INIT (XAB = FILE_XABFHC);
- STATUS = $OPEN (FAB = FILE_FAB);
-
- IF (.STATUS NEQ RMS$_NORMAL AND .STATUS NEQ RMS$_KFF)
- THEN
- BEGIN
- FILE_ERROR (.STATUS);
- RETURN KER_RMS32;
- END;
-
- !
- ! Now allocate a buffer for the records
- !
- REC_SIZE = (IF .FILE_TYPE EQL FILE_BLK THEN 512 ELSE .FILE_XABFHC [XAB$W_LRL]);
-
- IF .REC_SIZE EQL 0 THEN REC_SIZE = MAX_REC_LENGTH;
-
- STATUS = LIB$GET_VM (REC_SIZE, REC_ADDRESS);
- !
- ! Determine if we need a buffer for the fixed control area
- !
- FIX_SIZE = .FILE_FAB [FAB$B_FSZ];
-
- IF .FIX_SIZE NEQ 0
- THEN
- BEGIN
- STATUS = LIB$GET_VM (FIX_SIZE, FIX_ADDRESS);
- END;
-
- !
- ! Initialize the RAB for the $CONNECT RMS call
- !
- $RAB_INIT (RAB = FILE_RAB, FAB = FILE_FAB, RAC = SEQ, ROP = NLK, UBF = .REC_ADDRESS,
- USZ = .REC_SIZE);
-
- IF .FIX_SIZE NEQ 0 THEN FILE_RAB [RAB$L_RHB] = .FIX_ADDRESS;
-
- ! Store header address
- STATUS = $CONNECT (RAB = FILE_RAB);
-
- IF NOT .STATUS
- THEN
- BEGIN
- FILE_ERROR (.STATUS);
- RETURN KER_RMS32;
- END;
-
- FILE_REC_COUNT = -1;
- FILE_FAB [FAB$L_CTX] = F_STATE_PRE;
- RETURN KER_NORMAL;
- END; ! End of OPEN_READING
- %SBTTL 'FILE_OPEN'
-
- GLOBAL ROUTINE FILE_OPEN (FUNCTION) =
-
- !++
- ! FUNCTIONAL DESCRIPTION:
- !
- ! This routine will open a file for reading or writing depending on
- ! the function that is passed this routine. It will handle wildcards
- ! on the read function.
- !
- ! CALLING SEQUENCE:
- !
- ! status = FILE_OPEN(FUNCTION);
- !
- ! INPUT PARAMETERS:
- !
- ! FUNCTION - Function to do. Either FNC_READ or FNC_WRITE.
- !
- ! IMPLICIT INPUTS:
- !
- ! FILE_NAME and FILE_SIZE set up with the file name and the length
- ! of the name.
- !
- ! OUTPUT PARAMETERS:
- !
- ! None.
- !
- ! IMPLICIT OUTPUTS:
- !
- ! FILE_NAME and FILE_SIZE set up with the file name and the length
- ! of the name.
- !
- ! COMPLETION CODES:
- !
- ! KER_NORMAL - File opened correctly.
- ! KER_RMS32 - Problem processing the file.
- ! KER_INTERNALERR - Internal Kermit-32 error.
- !
- ! SIDE EFFECTS:
- !
- ! None.
- !
- !--
-
- BEGIN
- !
- ! Completion codes returned:
- !
- EXTERNAL LITERAL
- KER_NORMAL, ! Normal return
- KER_INTERNALERR, ! Internal error
- KER_RMS32; ! RMS-32 error
-
- EXTERNAL ROUTINE
- TT_TEXT : NOVALUE; ! Output an ASCIZ string
-
- EXTERNAL ROUTINE
- !
- ! This external routine is called to perform any checks on the file
- ! specification that the user wishes. It must return a true value
- ! if the access is to be allowed, and a false value (error code) if
- ! access is to be denied. The error code may be any valid system wide
- ! error code, any Kermit-32 error code (KER_xxx) or a user specific code,
- ! provided a message file defining the error code is loaded with Kermit-32.
- !
- ! The routine is called as:
- !
- ! STATUS = USER_FILE_CHECK ( FILE NAME DESCRIPTOR, READ/WRITE FLAG)
- !
- ! The file name descriptor points to the file specification supplied by
- ! the user. The read/write flag is TRUE if the file is being read, and
- ! false if it is being written.
- !
- USER_FILE_CHECK : ADDRESSING_MODE(GENERAL) WEAK;
-
- LOCAL
- STATUS, ! Random status values
- ITMLST : VECTOR [4, LONG], ! For GETDVI call
- SIZE : WORD; ! Size of resulting file name
-
- !
- ! Assume we can do searches
- !
- SEARCH_FLAG = TRUE;
- DEV_CLASS = DC$_DISK; ! Assume disk file
- !
- ! Now do the function dependent processing
- !
- FILE_MODE = .FUNCTION;
- FILE_DESC [DSC$W_LENGTH] = .FILE_SIZE; ! Length of file name
- !
- ! Call user routine (if any)
- !
- IF USER_FILE_CHECK NEQ 0
- THEN
- BEGIN
- STATUS = USER_FILE_CHECK (FILE_DESC, %REF (.FILE_MODE EQL FNC_READ));
- IF NOT .STATUS
- THEN
- BEGIN
- LIB$SIGNAL (.STATUS);
- RETURN .STATUS;
- END;
- END;
- !
- ! Select the correct routine depending on if we are reading or writing.
- !
-
- SELECTONE .FUNCTION OF
- SET
-
- [FNC_READ] :
- BEGIN
- !
- ! Determine device type
- !
- ITMLST [0] = DVI$_DEVCLASS^16 + 4; ! Want device class
- ITMLST [1] = DEV_CLASS; ! Put it there
- ITMLST [2] = ITMLST [2]; ! Put the size here
- ITMLST [3] = 0; ! End the list
- STATUS = $GETDVIW (DEVNAM = FILE_DESC, ITMLST = ITMLST);
- !
- ! If not a disk, can't do search
- !
- IF .STATUS AND .DEV_CLASS NEQ DC$_DISK THEN SEARCH_FLAG = FALSE;
-
- !
- ! Now set up the FAB with the information it needs.
- !
- $FAB_INIT (FAB = FILE_FAB, FOP = NAM, FNA = FILE_NAME, FNS = .FILE_SIZE,
- NAM = FILE_NAM, DNM = '.;0');
- !
- ! Now initialize the NAM block
- !
- $NAM_INIT (NAM = FILE_NAM, RSA = RES_STR, RSS = NAM$C_MAXRSS, ESA = EXP_STR,
- ESS = NAM$C_MAXRSS);
- !
- ! First parse the file specification.
- !
- STATUS = $PARSE (FAB = FILE_FAB);
-
- IF NOT .STATUS
- THEN
- BEGIN
- FILE_ERROR (.STATUS);
- RETURN KER_RMS32;
- END;
-
- IF .SEARCH_FLAG
- THEN
- BEGIN
- STATUS = $SEARCH (FAB = FILE_FAB);
-
- IF NOT .STATUS
- THEN
- BEGIN
- FILE_ERROR (.STATUS);
- RETURN KER_RMS32;
- END;
-
- END;
-
- !
- ! We now have an expanded file specification that we can use to process
- ! the file.
- !
- STATUS = OPEN_READING (); ! Open the file
-
- IF NOT .STATUS THEN RETURN .STATUS; ! If we couldn't, pass error back
-
- !
- ! Tell user what name we ended up with for storing the file
- !
-
- IF ( NOT .CONNECT_FLAG) AND .TY_FIL
- THEN
- BEGIN
-
- IF .FILE_NAM [NAM$B_RSS] GTR 0
- THEN
- BEGIN
- CH$WCHAR (CHR_NUL,
- CH$PTR (.FILE_NAM [NAM$L_RSA],
- .FILE_NAM [NAM$B_RSL]));
- TT_TEXT (.FILE_NAM [NAM$L_RSA]);
- END
- ELSE
- BEGIN
- CH$WCHAR (CHR_NUL,
- CH$PTR (.FILE_NAM [NAM$L_ESA],
- .FILE_NAM [NAM$B_ESL]));
- TT_TEXT (.FILE_NAM [NAM$L_ESA]);
- END;
-
- TT_TEXT (UPLIT (%ASCIZ' as '));
- END;
-
- END; ! End of [FNC_READ]
-
- [FNC_WRITE] :
- BEGIN
-
- SELECTONE .FILE_TYPE OF
- SET
-
- [FILE_ASC] :
- BEGIN
- $FAB_INIT (FAB = FILE_FAB, FAC = PUT, FNA = FILE_NAME,
- FNS = .FILE_SIZE, FOP = (MXV, CBT, SQO, TEF), NAM = FILE_NAM,
- ORG = SEQ, RFM = VAR, RAT = CR);
- END;
-
- [FILE_BIN] :
- BEGIN
- $FAB_INIT (FAB = FILE_FAB, FAC = PUT, FNA = FILE_NAME,
- FNS = .FILE_SIZE, FOP = (MXV, CBT, SQO, TEF), NAM = FILE_NAM,
- ORG = SEQ, RFM = VAR);
- END;
-
- [FILE_FIX] :
- BEGIN
- $FAB_INIT (FAB = FILE_FAB, FAC = PUT, FNA = FILE_NAME,
- FNS = .FILE_SIZE, FOP = (MXV, CBT, SQO, TEF), NAM = FILE_NAM,
- ORG = SEQ, RFM = FIX, MRS = (IF .file_blocksize_set
- THEN .file_blocksize
- ELSE 512));
- END;
-
- [FILE_BLK] :
- BEGIN
- $FAB_INIT (FAB = FILE_FAB, FAC = (PUT, BIO), FNA = FILE_NAME,
- FNS = .FILE_SIZE, FOP = (MXV, CBT, SQO, TEF), NAM = FILE_NAM);
- END;
- TES;
-
- !
- ! If we had an alternate file name from the receive command, use it
- ! instead of what KERMSG has told us.
- !
-
- IF .ALT_FILE_SIZE GTR 0
- THEN
- BEGIN
- LOCAL
- ALT_FILE_DESC : BLOCK [8, BYTE];
-
- ALT_FILE_DESC = .FILE_DESC;
- ALT_FILE_DESC [DSC$W_LENGTH] = .ALT_FILE_SIZE;
- ALT_FILE_DESC [DSC$A_POINTER] = ALT_FILE_NAME;
- IF USER_FILE_CHECK NEQ 0
- THEN
- BEGIN
- STATUS = USER_FILE_CHECK (ALT_FILE_DESC, %REF (.FILE_MODE EQL FNC_READ));
- IF NOT .STATUS
- THEN
- BEGIN
- LIB$SIGNAL (.STATUS);
- RETURN .STATUS;
- END;
- END;
- FILE_FAB [FAB$L_FNA] = ALT_FILE_NAME;
- FILE_FAB [FAB$B_FNS] = .ALT_FILE_SIZE;
- END;
-
- $NAM_INIT (NAM = FILE_NAM, ESA = EXP_STR, ESS = NAM$C_MAXRSS, RSA = RES_STR,
- RSS = NAM$C_MAXRSS);
- !
- ! Now allocate a buffer for the records
- !
- ! Determine correct buffer size
-
- SELECTONE .FILE_TYPE OF
- SET
-
- [FILE_ASC] :
- REC_SIZE = MAX_REC_LENGTH;
-
- [FILE_BIN] :
- REC_SIZE = (IF .file_blocksize_set THEN .file_blocksize
- ELSE 510);
-
- [FILE_BLK] :
- REC_SIZE = 512;
-
- [FILE_FIX] :
- REC_SIZE = (IF .file_blocksize_set THEN .file_blocksize
- ELSE 512);
-
- TES;
-
- STATUS = LIB$GET_VM (REC_SIZE, REC_ADDRESS);
- !
- ! Now create the file
- !
- STATUS = $CREATE (FAB = FILE_FAB);
-
- IF NOT .STATUS
- THEN
- BEGIN
- FILE_ERROR (.STATUS);
- RETURN KER_RMS32;
- END;
-
- $RAB_INIT (RAB = FILE_RAB, FAB = FILE_FAB, RAC = SEQ, RBF = .REC_ADDRESS,
- ROP = <NLK, WAT>);
- STATUS = $CONNECT (RAB = FILE_RAB);
-
- IF NOT .STATUS
- THEN
- BEGIN
- FILE_ERROR (.STATUS);
- RETURN KER_RMS32;
- END;
-
- !
- ! Set the initial state into the FAB field. This is used to remember
- ! whether we need to ignore the line feed which follows a carriage return.
- !
- FILE_FAB [FAB$L_CTX] = F_STATE_DATA;
- FILE_REC_COUNT = 0;
- FILE_REC_POINTER = CH$PTR (.REC_ADDRESS);
- !
- ! Tell user what name we ended up with for storing the file
- !
-
- IF ( NOT .CONNECT_FLAG) AND .TY_FIL
- THEN
- BEGIN
- TT_TEXT (UPLIT (%ASCIZ' as '));
-
- IF .FILE_NAM [NAM$B_RSL] GTR 0
- THEN
- BEGIN
- CH$WCHAR (CHR_NUL,
- CH$PTR (.FILE_NAM [NAM$L_RSA],
- .FILE_NAM [NAM$B_RSL]));
- TT_TEXT (.FILE_NAM [NAM$L_RSA]);
- END
- ELSE
- BEGIN
- CH$WCHAR (CHR_NUL,
- CH$PTR (.FILE_NAM [NAM$L_ESA],
- .FILE_NAM [NAM$B_ESL]));
- TT_TEXT (.FILE_NAM [NAM$L_ESA]);
- END;
-
- TT_OUTPUT ();
- END;
-
- END;
-
- [OTHERWISE] :
- RETURN KER_INTERNALERR;
- TES;
-
- !
- ! Copy the file name based on the type of file name we are to use.
- ! The possibilities are:
- ! Normal - Just copy name and type
- ! Full - Copy entire name string (either resultant or expanded)
- ! Untranslated - Copy string from name on (includes version, etc.)
-
- IF .DEV_CLASS EQL DC$_MAILBOX
- THEN
- BEGIN
- SIZE = 0;
- FILE_NAME = 0;
- END
- ELSE
-
- SELECTONE .FIL_NORMAL_FORM OF
- SET
-
- [FNM_FULL] :
- BEGIN
-
- IF .FILE_NAM [NAM$B_RSL] GTR 0
- THEN
- BEGIN
- CH$COPY (.FILE_NAM [NAM$B_RSL], CH$PTR (.FILE_NAM [NAM$L_RSA]),
- CHR_NUL, MAX_FILE_NAME, CH$PTR (FILE_NAME));
- SIZE = .FILE_NAM [NAM$B_RSL];
- END
- ELSE
- BEGIN
- CH$COPY (.FILE_NAM [NAM$B_ESL], CH$PTR (.FILE_NAM [NAM$L_ESA]),
- CHR_NUL, MAX_FILE_NAME, CH$PTR (FILE_NAME));
- SIZE = .FILE_NAM [NAM$B_ESL];
- END
-
- END;
-
- [FNM_NORMAL, FNM_UNTRAN] :
- BEGIN
- CH$COPY (.FILE_NAM [NAM$B_NAME], CH$PTR (.FILE_NAM [NAM$L_NAME]),
- .FILE_NAM [NAM$B_TYPE], CH$PTR (.FILE_NAM [NAM$L_TYPE]), CHR_NUL,
- MAX_FILE_NAME, CH$PTR (FILE_NAME));
- SIZE = .FILE_NAM [NAM$B_NAME] + .FILE_NAM [NAM$B_TYPE];
- END;
- TES;
-
- IF .SIZE GTR MAX_FILE_NAME THEN FILE_SIZE = MAX_FILE_NAME ELSE FILE_SIZE = .SIZE;
-
- RETURN KER_NORMAL;
- END; ! End of FILE_OPEN
-
- %SBTTL 'FILE_CLOSE'
-
- GLOBAL ROUTINE FILE_CLOSE (ABORT_FLAG) =
-
- !++
- ! FUNCTIONAL DESCRIPTION:
- !
- ! This routine will close a file that was opened by FILE_OPEN.
- ! It assumes any data associated with the file is stored in this
- ! module, since this routine is called by KERMSG.
- !
- ! CALLING SEQUENCE:
- !
- ! FILE_CLOSE();
- !
- ! INPUT PARAMETERS:
- !
- ! ABORT_FLAG - True if file should not be saved.
- !
- ! IMPLICIT INPUTS:
- !
- ! None.
- !
- ! OUTPUT PARAMETERS:
- !
- ! None.
- !
- ! IMPLICIT OUTPUTS:
- !
- ! None.
- !
- ! COMPLETION CODES:
- !
- ! None.
- !
- ! SIDE EFFECTS:
- !
- ! None.
- !
- !--
-
- BEGIN
- !
- ! Completion codes returned:
- !
- EXTERNAL LITERAL
- KER_NORMAL, ! Normal return
- KER_RMS32; ! RMS-32 error
-
- LOCAL
- STATUS; ! Random status values
-
- !
- ! If there might be something left to write
-
- !
-
- IF .FILE_MODE EQL FNC_WRITE AND (.FILE_REC_COUNT GTR 0 OR .FILE_FAB [FAB$L_CTX] NEQ
- F_STATE_DATA)
- THEN
- BEGIN
-
- SELECTONE .FILE_TYPE OF
- SET
-
- [FILE_FIX] :
- BEGIN
-
- INCR I FROM .FILE_REC_COUNT TO .REC_SIZE - 1 DO
- CH$WCHAR_A (CHR_NUL, FILE_REC_POINTER);
- FILE_REC_COUNT = .REC_SIZE; ! Store the byte count
- STATUS = DUMP_BUFFER ();
- END;
-
- [FILE_ASC, FILE_BIN] :
- STATUS = DUMP_BUFFER ();
-
- [FILE_BLK] :
- BEGIN
- FILE_RAB [RAB$W_RSZ] = .FILE_REC_COUNT;
- STATUS = $WRITE (RAB = FILE_RAB);
-
- IF NOT .STATUS
- THEN
- BEGIN
- FILE_ERROR (.STATUS);
- STATUS = KER_RMS32;
- END
- ELSE
- STATUS = KER_NORMAL;
-
- END;
- TES;
-
- IF NOT .STATUS THEN RETURN .STATUS;
-
- END;
-
- !
- ! If reading from a mailbox, read until EOF to allow the process on the other
- ! end to terminal gracefully.
- !
-
- IF .FILE_MODE EQL FNC_READ AND .DEV_CLASS EQL DC$_MAILBOX AND NOT .EOF_FLAG
- THEN
-
- DO
- STATUS = GET_BUFFER ()
- UNTIL ( NOT .STATUS) OR .EOF_FLAG;
-
- STATUS = LIB$FREE_VM (REC_SIZE, REC_ADDRESS);
-
- IF .FIX_SIZE NEQ 0 THEN STATUS = LIB$FREE_VM (FIX_SIZE, FIX_ADDRESS);
-
- IF .ABORT_FLAG AND .FILE_MODE EQL FNC_WRITE
- THEN
- FILE_FAB [FAB$V_DLT] = TRUE
- ELSE
- FILE_FAB [FAB$V_DLT] = FALSE;
-
- STATUS = $CLOSE (FAB = FILE_FAB);
- EOF_FLAG = FALSE;
-
- IF NOT .STATUS
- THEN
- BEGIN
- FILE_ERROR (.STATUS);
- RETURN KER_RMS32;
- END
- ELSE
- RETURN KER_NORMAL;
-
- END; ! End of FILE_CLOSE
-
- %SBTTL 'NEXT_FILE'
-
- GLOBAL ROUTINE NEXT_FILE =
-
- !++
- ! FUNCTIONAL DESCRIPTION:
- !
- ! This routine will cause the next file to be opened. It will
- ! call the RMS-32 routine $SEARCH and $OPEN for the file.
- !
- ! CALLING SEQUENCE:
- !
- ! STATUS = NEXT_FILE;
- !
- ! INPUT PARAMETERS:
- !
- ! None.
- !
- ! IMPLICIT INPUTS:
- !
- ! FAB/NAM blocks set up from previous processing.
- !
- ! OUTPUT PARAMETERS:
- !
- ! None.
- !
- ! IMPLICIT OUTPUTS:
- !
- ! FAB/NAM blocks set up for the next file.
- !
- ! COMPLETION CODES:
- !
- ! TRUE - There is a next file.
- ! KER_RMS32 - No next file.
- !
- ! SIDE EFFECTS:
- !
- ! None.
- !
- !--
-
- BEGIN
- !
- ! Completion codes returned:
- !
- EXTERNAL LITERAL
- KER_NORMAL, ! Normal return
- KER_NOMORFILES, ! No more files to read
- KER_RMS32; ! RMS-32 error
-
- EXTERNAL ROUTINE
- TT_TEXT : NOVALUE; ! Output an ASCIZ string
-
- LOCAL
- SIZE : WORD, ! Size of the $FAO string
- STATUS; ! Random status values
-
- !
- ! If we can't do a search, just return no more files
- !
-
- IF NOT .SEARCH_FLAG THEN RETURN KER_NOMORFILES;
-
- !
- ! Now search for the next file that we want to process.
- !
- STATUS = $SEARCH (FAB = FILE_FAB);
-
- IF .STATUS EQL RMS$_NMF THEN RETURN KER_NOMORFILES;
-
- IF NOT .STATUS
- THEN
- BEGIN
- FILE_ERROR (.STATUS);
- RETURN KER_RMS32;
- END;
-
- !
- ! Now we have the new file name. All that we have to do is open the file
- ! for reading now.
- !
- STATUS = OPEN_READING ();
-
- IF NOT .STATUS THEN RETURN .STATUS;
-
- !
- ! Copy the file name based on the type of file name we are to use.
- ! The possibilities are:
- ! Normal - Just copy name and type
- ! Full - Copy entire name string (either resultant or expanded)
- ! Untranslated - Copy string from name on (includes version, etc.)
-
- SELECTONE .FIL_NORMAL_FORM OF
- SET
-
- [FNM_FULL] :
- BEGIN
-
- IF .FILE_NAM [NAM$B_RSL] GTR 0
- THEN
- BEGIN
- CH$COPY (.FILE_NAM [NAM$B_RSL], CH$PTR (.FILE_NAM [NAM$L_RSA]), CHR_NUL,
- MAX_FILE_NAME, CH$PTR (FILE_NAME));
- SIZE = .FILE_NAM [NAM$B_RSL];
- END
- ELSE
- BEGIN
- CH$COPY (.FILE_NAM [NAM$B_ESL], CH$PTR (.FILE_NAM [NAM$L_ESA]), CHR_NUL,
- MAX_FILE_NAME, CH$PTR (FILE_NAME));
- SIZE = .FILE_NAM [NAM$B_ESL];
- END
-
- END;
-
- [FNM_NORMAL, FNM_UNTRAN] :
- BEGIN
- CH$COPY (.FILE_NAM [NAM$B_NAME], CH$PTR (.FILE_NAM [NAM$L_NAME]),
- .FILE_NAM [NAM$B_TYPE], CH$PTR (.FILE_NAM [NAM$L_TYPE]), CHR_NUL,
- MAX_FILE_NAME, CH$PTR (FILE_NAME));
- SIZE = .FILE_NAM [NAM$B_NAME] + .FILE_NAM [NAM$B_TYPE];
- END;
- TES;
-
- IF .SIZE GTR MAX_FILE_NAME THEN FILE_SIZE = MAX_FILE_NAME ELSE FILE_SIZE = .SIZE;
-
- !
- ! Put prompt for NEXT_FILE sending in here
- !
- IF ( NOT .CONNECT_FLAG) AND .TY_FIL
- THEN
- BEGIN
- TT_TEXT (UPLIT (%ASCIZ 'Sending: '));
- .FILE_NAM [NAM$L_RSA] + .FILE_NAM [NAM$B_RSL] = 0;
- TT_TEXT (.FILE_NAM [NAM$L_RSA]);
- TT_TEXT (UPLIT (%ASCIZ ' as '));
- TT_OUTPUT ();
- END;
-
- RETURN KER_NORMAL;
- END; ! End of NEXT_FILE
-
- %SBTTL 'LOG_OPEN - Open a log file'
-
- GLOBAL ROUTINE LOG_OPEN (LOG_DESC, LOG_FAB, LOG_RAB) =
-
- !++
- ! FUNCTIONAL DESCRIPTION:
- !
- ! CALLING SEQUENCE:
- !
- ! STATUS = LOG_OPEN (LOG_DESC, LOG_FAB, LOG_RAB)
- !
- ! INPUT PARAMETERS:
- !
- ! LOG_DESC - Address of descriptor for file name to be opened
- !
- ! LOG_FAB - Address of FAB for file
- !
- ! LOG_RAB - Address of RAB for file
- !
- ! IMPLICIT INPUTS:
- !
- ! None.
- !
- ! OUPTUT PARAMETERS:
- !
- ! LOG_FAB and LOG_RAB updated.
- !
- ! IMPLICIT OUTPUTS:
- !
- ! None.
- !
- ! COMPLETION CODES:
- !
- ! Error code or true.
- !
- ! SIDE EFFECTS:
- !
- ! None.
- !
- !--
-
- BEGIN
- !
- ! Completion codes returned:
- !
- EXTERNAL LITERAL
- KER_NORMAL, ! Normal return
- KER_RMS32; ! RMS-32 error
-
- MAP
- LOG_DESC : REF BLOCK [8, BYTE], ! Name descriptor
- LOG_FAB : REF $FAB_DECL, ! FAB for file
- LOG_RAB : REF $RAB_DECL; ! RAB for file
-
- LOCAL
- STATUS, ! Random status values
- REC_ADDRESS, ! Address of record buffer
- REC_SIZE; ! Size of record buffer
-
- !
- ! Get memory for records
- !
- REC_SIZE = LOG_BUFF_SIZE;
- STATUS = LIB$GET_VM (REC_SIZE, REC_ADDRESS);
-
- IF NOT .STATUS
- THEN
- BEGIN
- LIB$SIGNAL (.STATUS);
- RETURN .STATUS;
- END;
-
- !
- ! Initialize the FAB and RAB
- !
- $FAB_INIT (FAB = .LOG_FAB, FAC = PUT, FNA = .LOG_DESC [DSC$A_POINTER],
- FNS = .LOG_DESC [DSC$W_LENGTH], FOP = (MXV, CBT, SQO, TEF), ORG = SEQ, RFM = VAR,
- RAT = CR, CTX = 0, DNA = UPLIT (%ASCII'.LOG'), DNS = 4);
- STATUS = $CREATE (FAB = .LOG_FAB);
-
- IF NOT .STATUS
- THEN
- BEGIN
- FILE_ERROR (.STATUS);
- LIB$FREE_VM (REC_SIZE, REC_ADDRESS); ! Dump record buffer
- RETURN KER_RMS32;
- END;
-
- $RAB_INIT (RAB = .LOG_RAB, FAB = .LOG_FAB, RAC = SEQ, RBF = .REC_ADDRESS,
- RSZ = .REC_SIZE, UBF = .REC_ADDRESS, USZ = .REC_SIZE, ROP = <NLK, WAT>, CTX = 0);
- STATUS = $CONNECT (RAB = .LOG_RAB);
-
- IF NOT .STATUS
- THEN
- BEGIN
- FILE_ERROR (.STATUS);
- LIB$FREE_VM (REC_SIZE, REC_ADDRESS);
- $CLOSE (FAB = .LOG_FAB);
- RETURN KER_RMS32;
- END
- ELSE
- RETURN .STATUS;
-
- END; ! End of LOG_OPEN
-
- %SBTTL 'LOG_CLOSE - Close a log file'
-
- GLOBAL ROUTINE LOG_CLOSE (LOG_FAB, LOG_RAB) =
-
- !++
- ! FUNCTIONAL DESCRIPTION:
- !
- ! This routine will close an open log file. It will also ensure that
- !the last buffer gets dumped.
- !
- ! CALLING SEQUENCE:
- !
- ! STATUS = LOG_CLOSE (LOG_FAB, LOG_RAB);
- !
- ! INPUT PARAMETERS:
- !
- ! LOG_FAB - Address of log file FAB
- !
- ! LOG_RAB - Address of log file RAB
- !
- ! IMPLICIT INPUTS:
- !
- ! None.
- !
- ! OUPTUT PARAMETERS:
- !
- ! None.
- !
- ! IMPLICIT OUTPUTS:
- !
- ! None.
- !
- ! COMPLETION CODES:
- !
- ! Resulting status.
- !
- ! SIDE EFFECTS:
- !
- ! None.
- !
- !--
-
- BEGIN
- !
- ! Completion codes returned:
- !
- EXTERNAL LITERAL
- KER_RMS32; ! RMS-32 error
-
- MAP
- LOG_FAB : REF $FAB_DECL, ! FAB for log file
- LOG_RAB : REF $RAB_DECL; ! RAB for log file
-
- LOCAL
- STATUS, ! Random status values
- REC_ADDRESS, ! Address of record buffer
- REC_SIZE; ! Size of record buffer
-
- !
- ! First write out any outstanding data
- !
-
- IF .LOG_RAB [RAB$L_CTX] GTR 0 THEN LOG_PUT (.LOG_RAB); ! Dump current buffer
-
- !
- ! Return the buffer
- !
- REC_SIZE = LOG_BUFF_SIZE; ! Get size of buffer
- REC_ADDRESS = .LOG_RAB [RAB$L_RBF]; ! And address
- LIB$FREE_VM (REC_SIZE, REC_ADDRESS);
- !
- ! Now disconnect the RAB
- !
- STATUS = $DISCONNECT (RAB = .LOG_RAB);
-
- IF NOT .STATUS
- THEN
- BEGIN
- FILE_ERROR (.STATUS);
- RETURN KER_RMS32;
- END;
-
- !
- ! Now we can close the file
- !
- STATUS = $CLOSE (FAB = .LOG_FAB);
-
- IF NOT .STATUS THEN FILE_ERROR (.STATUS);
-
- !
- ! And return the result
- !
- RETURN .STATUS;
- END; ! End of LOG_CLOSE
-
- %SBTTL 'LOG_CHAR - Log a character to a file'
-
- GLOBAL ROUTINE LOG_CHAR (CH, LOG_RAB) =
-
- !++
- ! FUNCTIONAL DESCRIPTION:
- !
- ! This routine will write one character to an open log file.
- !If the buffer becomes filled, it will dump it. It will also
- !dump the buffer if a carriage return line feed is seen.
- !
- ! CALLING SEQUENCE:
- !
- ! STATUS = LOG_CHAR (.CH, LOG_RAB);
- !
- ! INPUT PARAMETERS:
- !
- ! CH - The character to write to the file.
- !
- ! LOG_RAB - The address of the log file RAB.
- !
- ! IMPLICIT INPUTS:
- !
- ! None.
- !
- ! OUPTUT PARAMETERS:
- !
- ! None.
- !
- ! IMPLICIT OUTPUTS:
- !
- ! None.
- !
- ! COMPLETION CODES:
- !
- ! Any error returned by LOG_PUT, else TRUE.
- !
- ! SIDE EFFECTS:
- !
- ! None.
- !
- !--
-
- BEGIN
- !
- ! Completion codes returned:
- !
- EXTERNAL LITERAL
- KER_NORMAL; ! Normal return
-
- MAP
- LOG_RAB : REF $RAB_DECL; ! Log file RAB
-
- LOCAL
- STATUS; ! Random status value
-
- !
- ! If this character is a line feed, and previous was a carriage return, then
- ! dump the buffer and return.
- !
-
- IF .CH EQL CHR_LFD
- THEN
- BEGIN
- !
- ! If we seem to have overfilled the buffer, that is because we saw a CR
- ! last, and had no place to put it. Just reset the size and dump the buffer.
- !
-
- IF .LOG_RAB [RAB$L_CTX] GTR LOG_BUFF_SIZE
- THEN
- BEGIN
- LOG_RAB [RAB$L_CTX] = LOG_BUFF_SIZE;
- RETURN LOG_PUT (.LOG_RAB);
- END;
-
- !
- ! If last character in buffer is a CR, then dump buffer without the CR
- !
-
- IF CH$RCHAR (CH$PTR (.LOG_RAB [RAB$L_RBF], .LOG_RAB [RAB$L_CTX] - 1)) EQL CHR_CRT
- THEN
- BEGIN
- LOG_RAB [RAB$L_CTX] = .LOG_RAB [RAB$L_CTX] - 1;
- RETURN LOG_PUT (.LOG_RAB);
- END;
-
- END;
-
- !
- ! Don't need to dump buffer because of end of line problems. Check if
- ! the buffer is full.
- !
-
- IF .LOG_RAB [RAB$L_CTX] GEQ LOG_BUFF_SIZE
- THEN
- BEGIN
- !
- ! If character we want to store is a carriage return, then just count it and
- ! don't dump the buffer yet.
- !
-
- IF .CH EQL CHR_CRT
- THEN
- BEGIN
- LOG_RAB [RAB$L_CTX] = .LOG_RAB [RAB$L_CTX] + 1;
- RETURN KER_NORMAL;
- END;
-
- !
- ! We must dump the buffer to make room for more characters
- !
- STATUS = LOG_PUT (.LOG_RAB);
-
- IF NOT .STATUS THEN RETURN .STATUS;
-
- END;
-
- !
- ! Here when we have some room to store the character
- !
- CH$WCHAR (.CH, CH$PTR (.LOG_RAB [RAB$L_RBF], .LOG_RAB [RAB$L_CTX]));
- LOG_RAB [RAB$L_CTX] = .LOG_RAB [RAB$L_CTX] + 1;
- RETURN KER_NORMAL;
- END; ! End of LOG_CHAR
-
- %SBTTL 'LOG_LINE - Log a line to a log file'
-
- GLOBAL ROUTINE LOG_LINE (LINE_DESC, LOG_RAB) =
-
- !++
- ! FUNCTIONAL DESCRIPTION:
- !
- ! This routine will write an entire line to a log file. And previously
- ! written characters will be dumped first.
- !
- ! CALLING SEQUENCE:
- !
- ! STATUS = LOG_LINE (LINE_DESC, LOG_RAB);
- !
- ! INPUT PARAMETERS:
- !
- ! LINE_DESC - Address of descriptor for string to be written
- !
- ! LOG_RAB - RAB for log file
- !
- ! IMPLICIT INPUTS:
- !
- ! None.
- !
- ! OUPTUT PARAMETERS:
- !
- ! None.
- !
- ! IMPLICIT OUTPUTS:
- !
- ! None.
- !
- ! COMPLETION CODES:
- !
- ! KER_NORMAL or LOG_PUT error code.
- !
- ! SIDE EFFECTS:
- !
- ! None.
- !
- !--
-
- BEGIN
-
- MAP
- LINE_DESC : REF BLOCK [8, BYTE], ! Descriptor for string
- LOG_RAB : REF $RAB_DECL; ! RAB for file
-
- LOCAL
- STATUS; ! Random status value
-
- !
- ! First check if anything is already in the buffer
- !
-
- IF .LOG_RAB [RAB$L_CTX] GTR 0
- THEN
- BEGIN
- STATUS = LOG_PUT (.LOG_RAB); ! Yes, write it out
-
- IF NOT .STATUS THEN RETURN .STATUS; ! Pass back any errors
-
- END;
-
- !
- ! Copy the data to the buffer
- !
- CH$COPY (.LINE_DESC [DSC$W_LENGTH], CH$PTR (.LINE_DESC [DSC$A_POINTER]), CHR_NUL,
- LOG_BUFF_SIZE, CH$PTR (.LOG_RAB [RAB$L_RBF]));
-
- IF .LINE_DESC [DSC$W_LENGTH] GTR LOG_BUFF_SIZE
- THEN
- LOG_RAB [RAB$L_CTX] = LOG_BUFF_SIZE
- ELSE
- LOG_RAB [RAB$L_CTX] = .LINE_DESC [DSC$W_LENGTH];
-
- !
- ! Now just dump the buffer
- !
- RETURN LOG_PUT (.LOG_RAB);
- END; ! End of LOG_LINE
- %SBTTL 'LOG_FAOL - Log an FAO string to the log file'
-
- GLOBAL ROUTINE LOG_FAOL (FAOL_DESC, FAOL_PARAMS, LOG_RAB) =
-
- !++
- ! FUNCTIONAL DESCRIPTION:
- !
- ! This routine will write an FAOL string to the output file.
- !
- ! CALLING SEQUENCE:
- !
- ! STATUS = LOG_FAOL (FAOL_DESC, FAOL_PARAMS, LOG_RAB);
- !
- ! INPUT PARAMETERS:
- !
- ! FAOL_DESC - Address of descriptor for string to be written
- !
- ! FAOL_PARAMS - Parameter list for FAOL call
- !
- ! LOG_RAB - RAB for log file
- !
- ! IMPLICIT INPUTS:
- !
- ! None.
- !
- ! OUPTUT PARAMETERS:
- !
- ! None.
- !
- ! IMPLICIT OUTPUTS:
- !
- ! None.
- !
- ! COMPLETION CODES:
- !
- ! KER_NORMAL or $FAOL or LOG_PUT error code.
- !
- ! SIDE EFFECTS:
- !
- ! None.
- !
- !--
-
- BEGIN
- !
- ! Completion codes returned:
- !
- EXTERNAL LITERAL
- KER_NORMAL; ! Normal return
-
- MAP
- FAOL_DESC : REF BLOCK [8, BYTE], ! Descriptor for string
- LOG_RAB : REF $RAB_DECL; ! RAB for file
-
- LITERAL
- FAOL_BUFSIZ = 256; ! Length of buffer
-
- LOCAL
- FAOL_BUFFER : VECTOR [FAOL_BUFSIZ, BYTE], ! Buffer for FAOL output
- FAOL_BUF_DESC : BLOCK [8, BYTE], ! Descriptor for buffer
- STATUS; ! Random status value
-
- !
- ! Initialize descriptor for buffer
- !
- FAOL_BUF_DESC [DSC$B_CLASS] = DSC$K_CLASS_S;
- FAOL_BUF_DESC [DSC$B_DTYPE] = DSC$K_DTYPE_T;
- FAOL_BUF_DESC [DSC$A_POINTER] = FAOL_BUFFER;
- FAOL_BUF_DESC [DSC$W_LENGTH] = FAOL_BUFSIZ;
- !
- ! Now do the FAOL to generate the full text
- !
- STATUS = $FAOL (CTRSTR = .FAOL_DESC, OUTBUF = FAOL_BUF_DESC,
- OUTLEN = FAOL_BUF_DESC [DSC$W_LENGTH], PRMLST = .FAOL_PARAMS);
- IF NOT .STATUS THEN RETURN .STATUS;
- !
- ! Dump the text into the file
- !
- INCR I FROM 1 TO .FAOL_BUF_DESC [DSC$W_LENGTH] DO
- BEGIN
- STATUS = LOG_CHAR ( .FAOL_BUFFER [.I - 1], .LOG_RAB);
- IF NOT .STATUS THEN RETURN .STATUS;
- END;
-
- RETURN KER_NORMAL;
-
- END; ! End of LOG_FAOL
-
- %SBTTL 'LOG_PUT - Write a record buffer for a log file'
- ROUTINE LOG_PUT (LOG_RAB) =
-
- !++
- ! FUNCTIONAL DESCRIPTION:
- !
- ! This routine will output one buffer for a log file.
- !
- ! CALLING SEQUENCE:
- !
- ! STATUS = LOG_PUT (LOG_RAB);
- !
- ! INPUT PARAMETERS:
- !
- ! LOG_RAB - RAB for log file.
- !
- ! IMPLICIT INPUTS:
- !
- ! None.
- !
- ! OUPTUT PARAMETERS:
- !
- ! None.
- !
- ! IMPLICIT OUTPUTS:
- !
- ! None.
- !
- ! COMPLETION CODES:
- !
- ! Status value from RMS
- !
- ! SIDE EFFECTS:
- !
- ! None.
- !
- !--
-
- BEGIN
-
- MAP
- LOG_RAB : REF $RAB_DECL; ! RAB for file
-
- !
- ! Calculate record size
- !
- LOG_RAB [RAB$W_RSZ] = .LOG_RAB [RAB$L_CTX];
- LOG_RAB [RAB$W_USZ] = .LOG_RAB [RAB$W_RSZ];
- !
- ! Buffer will be empty when we finish
- !
- LOG_RAB [RAB$L_CTX] = 0;
- !
- ! And call RMS to write the buffer
- !
- RETURN $PUT (RAB = .LOG_RAB);
- END; ! End of LOG_PUT
- %SBTTL 'FILE_ERROR - Error processing for all RMS errors'
- ROUTINE FILE_ERROR (STATUS) : NOVALUE =
-
- !++
- ! FUNCTIONAL DESCRIPTION:
- !
- ! This routine will process all of the RMS-32 error returns. It will
- ! get the text for the error and then it will issue a KER_ERROR for
- ! the RMS failure.
- !
- ! CALLING SEQUENCE:
- !
- ! FILE_ERROR();
- !
- ! INPUT PARAMETERS:
- !
- ! None.
- !
- ! IMPLICIT INPUTS:
- !
- ! STATUS - RMS error status.
- ! FILE_NAME - File name and extension.
- ! FILE_SIZE - Size of the thing in FILE_NAME.
- !
- ! OUTPUT PARAMETERS:
- !
- ! None.
- !
- ! IMPLICIT OUTPUTS:
- !
- ! None.
- !
- ! COMPLETION CODES:
- !
- ! None.
- !
- ! SIDE EFFECTS:
- !
- ! None.
- !
- !--
-
- BEGIN
- !
- ! KERMIT completion codes
- !
- EXTERNAL LITERAL
- KER_RMS32; ! RMS-32 error
-
- LOCAL
- ERR_BUFFER : VECTOR [CH$ALLOCATION (MAX_MSG)],
- ERR_DESC : BLOCK [8, BYTE] PRESET ! String descriptor to
- ([DSC$B_CLASS ] = DSC$K_CLASS_S, ! the error buffer
- [DSC$B_DTYPE ] = DSC$K_DTYPE_T, ! standard string
- [DSC$W_LENGTH ] = MAX_MSG, ! descriptor
- [DSC$A_POINTER ] = ERR_BUFFER);
-
- $GETMSG (MSGID = .STATUS,
- MSGLEN = ERR_DESC [DSC$W_LENGTH],
- BUFADR = ERR_DESC,
- FLAGS = 1);
- LIB$SIGNAL (KER_RMS32, 2, ERR_DESC, FILE_DESC);
- END; ! End of FILE_ERROR
- %SBTTL 'End of KERFIL'
- END ! End of module
-
- ELUDOM
-